﻿using System;
using System.Collections.Generic;
using System.Text;
using Model = SharePointOptimizer.Model;
using System.Linq;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Data.SqlTypes;
using AG.Utilities;
using SharePointOptimizer.Model;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace SharePointOptimizer.SQLServer
{

    public class CollectSharePointContentData
    {
        List<Exception> errors;
        SharePointOptimizerDataContext dc;

        public List<Exception> Collect()
        {
           
            try
            {
                errors = new List<Exception>();
                dc = new SharePointOptimizerDataContext(System.Configuration.ConfigurationManager.AppSettings["ConnectionStringSSHCDatabase"].ToString());
               // dc.ClearAll();
                
                //TODO: KK Put collection code here
                SPFarm farm = SPFarm.Local;
               
                foreach (SPService svc in farm.Services)
                {

                    if (svc is SPWebService)
                    {
                        SPWebService webSvc = (SPWebService)svc;
                        foreach (SPWebApplication webApp in webSvc.WebApplications)
                        {
                           
                            foreach (SPSite siteCol in webApp.Sites)
                            {
                                SiteCollection newSiteCol = new SiteCollection();
                                fillSiteCol(siteCol, newSiteCol);
                                newSiteCol.WebApplicationID = siteCol.WebApplication.Id;
                                dc.SiteCollections.InsertOnSubmit(newSiteCol);
                                dc.SubmitChanges();

                                foreach (SPWeb siteColWeb in siteCol.AllWebs)
                                {
                                    Web newWeb = new Web();
                                  //  siteColWeb.role1
                                   // web.SiteCollection = newSiteCol;
                                    fillWeb(siteColWeb, newSiteCol, newWeb,0);
                                    
                                    //dc.Webs.InsertOnSubmit(web);
                                   // dc.SubmitChanges();
                                    foreach (SPList list in siteColWeb.Lists)
                                    {
                                        List newList = new List();
                                        newList.Web = newWeb;
                                        fillList(list, newList);
                                        
                                        dc.Lists.InsertOnSubmit(newList);
                                        dc.SubmitChanges();
                                        foreach (SPView view in list.Views)
                                        {
                                            SharePointOptimizer.Model.View newView = new SharePointOptimizer.Model.View();
                                            newView.List = newList;
                                            fillView(view, newView);
                                            dc.Views.InsertOnSubmit(newView);
                                            dc.SubmitChanges();
                                        }
                                    }
                                    foreach (SPUser user in siteColWeb.Users)
                                    {
                                        User newUser = new User();
                                        Web_User web_user = new Web_User();
                                        web_user.User = newUser;
                                        web_user.Web = newWeb;
                                        fillUser(user, newUser);
                                        dc.Users.InsertOnSubmit(newUser);
                                        dc.Web_Users.InsertOnSubmit(web_user);
                                        dc.SubmitChanges();
                                        foreach (SPRole roledef in user.Roles)
                                        {
                                            Role newRole = new Role();
                                            User_Role user_role = new User_Role();
                                            user_role.User = newUser;
                                            user_role.Role = newRole;
                                            fillRole(roledef, newRole);
                                            dc.Roles.InsertOnSubmit(newRole);
                                            dc.User_Roles.InsertOnSubmit(user_role);
                                            dc.SubmitChanges();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
           
            }
            catch (Exception ex1)
            {
                Logger.Error(ex1);
            }

            return errors;
        }
        void fillUser(SPUser user, User newUser)
        {
            newUser.AllowBrowseUserInfo = user.AllowBrowseUserInfo;
            newUser.IsApplicationPrincipal = user.IsApplicationPrincipal;
            newUser.IsDomainGroup = user.IsDomainGroup;
            newUser.IsSiteAdmin = user.IsSiteAdmin;
            newUser.IsSiteAuditor = user.IsSiteAuditor;
            newUser.Login = user.LoginName;
            newUser.Name = user.Name;
            newUser.UserID = user.ID;
        }
        void fillRole(SPRole role, Role newRole)
        {
            newRole.Description = role.Description;
            //newRole.Hidden = role.Hidden;
            newRole.ParentWeb = role.ParentWeb.ID;
            newRole.Name = role.Name;
           // newRole.RoleID = role.Id;
            newRole.Type = role.Type.ToString();
            newRole.XML = role.Xml;
        }
        void fillWeb(SPWeb web, SiteCollection newSiteCol, Web newWeb, int level)
        {
           
            newWeb.SiteCollection = newSiteCol;

            newWeb.nrFiles = GetWebNrFiles(web);
            newWeb.WebID = web.ID;
            //newWeb.AuthenticationMode = web.AuthenticationMode.ToString();
            newWeb.ParentWebID = web.ParentWebId;
            newWeb.Size = GetWebSize(web);
            newWeb.Level = level;
            newWeb.ServerRelativeUrl = web.Url;
            dc.Webs.InsertOnSubmit(newWeb);
            dc.SubmitChanges();
            foreach (SPWeb subweb in web.Webs)
            {
                Web newSubWeb = new Web();
                fillWeb(subweb, newSiteCol, newSubWeb, level + 1);
            }


        }
        void fillList(SPList list, List newList)
        {
            if (list is SPDocumentLibrary)
            {
                newList.isDocumentLibrary = true;
                //newList.URL = list.ParentWebUrl +"" + list.Title;
            }
            else
            {
                newList.isDocumentLibrary = false;
                //newList.URL = list.ParentWebUrl + "/lists/" + list.Title;
            }
        //    newList.Size = GetListSize(list);
            newList.URL = newList.Web.ServerRelativeUrl + "/" + list.RootFolder.Url;
            newList.ListID = list.ID;

            newList.Title = list.Title;

            newList.BaseType = list.BaseType.ToString();

            newList.IsSiteAssetsLibrary = list.IsSiteAssetsLibrary;
            newList.ItemCount = list.ItemCount;

            newList.RootFolder = list.RootFolder.ToString();
            newList.Size = GetListSize(list);
            newList.Version = list.Version;

        }
        void fillSiteCol(SPSite siteCol, SiteCollection newSiteCol)
        {
            //siteCol.user
            newSiteCol.Size = siteCol.Usage.Storage;
            newSiteCol.SiteCollectionID = siteCol.ID;
            newSiteCol.UpgradeRedirectUri = siteCol.UpgradeRedirectUri.ToString();
            newSiteCol.ContentDatabaseID = siteCol.ContentDatabase.Id;
    


        }
        void fillView(SPView view, SharePointOptimizer.Model.View newView)
        {
            newView.ViewID = view.ID;
            newView.BaseViewID = view.BaseViewID;
            newView.Scope = view.Scope.ToString();
            newView.StyleID = view.StyleID;
            newView.Title = view.Title;
            newView.Type = view.Type;
            newView.RowLimit = (int)view.RowLimit;
            newView.FieldsCount = view.ViewFields.Count;



        }
        private double GetWebSize(SPWeb web)
        {
            double total = 0;

            foreach (SPFolder folder in web.Folders)
            {
                total += GetFolderSize(folder);
            }

            foreach (SPWeb subweb in web.Webs)
            {
                total += GetWebSize(subweb);
                subweb.Dispose();
            }

            return total / 1048576;
        }
        private double GetListSize(SPList list)
        {
            double total = 0;

            foreach (SPListItem listItem in list.Items)
            {
                try { total += listItem.File.Length; }
                catch { }
            }


            return total / 1048576;
        }

        private long GetFolderSize(SPFolder folder)
        {
            long folderSize = 0;

            foreach (SPFile file in folder.Files)
            {
                folderSize += file.Length;
            }

            foreach (SPFolder subfolder in folder.SubFolders)
            {
                folderSize += GetFolderSize(subfolder);
            }

            return folderSize;
        }
        private long GetListItemSize(SPListItem listItem)
        {
            long folderSize = 0;
            SPFile file = listItem.File;
            return file.Length;

           // return folderSize;
        }
        private long GetWebNrFiles(SPWeb web)
        {
            long total = 0;

            foreach (SPFolder folder in web.Folders)
            {
                total += folder.Files.Count;
            }

            foreach (SPWeb subweb in web.Webs)
            {
                total += GetWebNrFiles(subweb);
                subweb.Dispose();
            }

            return total;
        }
    }
}